package com.bestcem.xm.member.controller;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.common.core.uitls.StringUtil;
import com.bestcem.xm.component.security.annotation.AuthIgnore;
import com.bestcem.xm.label.dao.mapper.LabelGroupMapper;
import com.bestcem.xm.label.dao.mapper.LabelMapper;
import com.bestcem.xm.label.dao.mapper.LabelValueMapper;
import com.bestcem.xm.label.entity.mysql.LabelEntity;
import com.bestcem.xm.label.entity.mysql.LabelGroupEntity;
import com.bestcem.xm.label.entity.mysql.LabelValueEntity;
import com.bestcem.xm.member.controller.param.HttpMemberFieldParam;
import com.bestcem.xm.member.controller.param.HttpMemberLabelParam;
import com.bestcem.xm.member.dao.mapper.*;
import com.bestcem.xm.member.entity.mysql.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 创建数据
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/10/15
 */
@RestController
@RequestMapping("/member")
public class CreateDataController {

    @Resource
    private MemberMapper memberMapper;

    @Resource
    private ExtendFieldMapper extendFieldMapper;

    @Resource
    private LabelGroupMapper labelGroupMapper;

    @Resource
    private LabelValueMapper labelValueMapper;

    @Resource
    private LabelMapper labelMapper;

    @Resource
    private FootprintMapper footprintMapper;

    @Resource
    private ExportRecordMapper exportRecordMapper;

    @Resource
    private ImportRecordMapper importRecordMapper;

    @Resource
    private DisplayRangeMapper displayRangeMapper;

    @Resource
    private MemberProjectMapper memberProjectMapper;


    private final ThreadPoolExecutor BUILD_MEMBER_THREAD_POOL = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5000));

    /**
     * - 从orgId池子中得到一个orgId 【传入orgId，输入一个联系人数量】。
     * - 创建3个标签组
     * -    3个标签
     * -        3个标签值
     * - 创建5扩展字段
     * - 创建N个联系人任务，丢入到线程池
     */
    @AuthIgnore
    @PostMapping(value = "/createData")
    public void createData() {
        // 生成组织id以及对应组织所需要创建的联系人数量
        Map<String, Integer> orgMap = genOrgMap();
        // 遍历组织map，生成对应的联系人信息以及扩展字段与标签信息
        orgMap.forEach(this::buildMemberData);
    }

    /**
     * 每一个组织 2个标签组 2个标签 1~2个标签值
     * 需 60000 标签组
     * 120000 标签
     * 180000 标签值
     */
    @AuthIgnore
    @PostMapping(value = "/createLabel")
    public void createLabel() {
        for (int i = 0; i < 30000; i++) {
            String orgId = StringUtil.getId();
            buildLabel(orgId);
        }
    }

    /**
     * 制造 导入日志
     * 制造 导出日志
     * 项目列表
     * 联系方式可见范围数据
     */
    @AuthIgnore
    @PostMapping(value = "/v2/createData")
    public void createData2() {
        List<String> orgList = genOrgMap2();
        orgList.forEach(orgId -> {
            buildExportLog(orgId);
            buildImportLog(orgId);
            buildDisplayRange(orgId);
            buildProject(orgId);
        });
    }

    void buildExportLog(String orgId) {
        List<ExportRecordEntity> entities = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            ExportRecordEntity entity = new ExportRecordEntity();
            entity.setStatus(0);
            entity.setOrgId(orgId);
            entity.setOpUserId("6144477fce3fb403c28316b5");
            entity.setMemberType(0);
            entity.setExportId(StringUtil.getId());
            entity.setCreateTime(DateUtil.getCommonDate());
            entity.setUpdateTime(entity.getCreateTime());
            entities.add(entity);
        }
        exportRecordMapper.batchSave(entities);
    }

    void buildImportLog(String orgId) {
        List<ImportRecordEntity> entities = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            ImportRecordEntity entity = new ImportRecordEntity();
            entity.setStatus(0);
            entity.setOrgId(orgId);
            entity.setOpUserId("6144477fce3fb403c28316b5");
            entity.setMemberType(0);
            entity.setFailedCount(0);
            entity.setReceiveCount(0);
            entity.setSuccessCount(0);
            entity.setId(StringUtil.getId());
            entities.add(entity);
        }

        importRecordMapper.batchSave(entities);
    }

    void buildDisplayRange(String orgId) {
        List<DisplayRangeEntity> entities = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            DisplayRangeEntity entity = new DisplayRangeEntity();
            entity.setDisplayId(StringUtil.getId());
            entity.setOrgId(orgId);
            entity.setRoleIds("[]");
            entity.setMemberType(i);
            entity.setType(0);
            entity.setCreateTime(DateUtil.getCommonDate());
            entity.setUpdateTime(entity.getCreateTime());
            entities.add(entity);
        }
        displayRangeMapper.batchSave(entities);
    }

    void buildProject(String orgId) {
        // 616e3e3944693b16da250e7f
        List<MemberProjectEntity> entries = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            MemberProjectEntity entity = new MemberProjectEntity();
            entity.setOrgId(orgId);
            entity.setCode("123131");
            entity.setMemberId("616e3e3944693b16da250e7f");
            entity.setProjectId(StringUtil.getId());
            entity.setCreateTime(DateUtil.getCommonDate());
            entity.setUpdateTime(entity.getCreateTime());
            entries.add(entity);
        }
        memberProjectMapper.batchInsert(entries);

    }

    private List<String> genOrgMap2() {
        List<String> orgList = new ArrayList<>();
        orgList.add("5e378a1eaace70000aa8fe78");
        orgList.add("614aea718b57a8e40fe9bb11");
        orgList.add("6144477f7c39f32d7c2120f4");
        for (int i = 0; i < 1_00000; i++) {
            orgList.add(StringUtil.getId());
        }
        return orgList;
    }

    /**
     * orgId池子 包含 orgid 和 改orgId 下的 联系人数量
     *
     * @return 组织id对应联系人数量的池子
     */
    private Map<String, Integer> genOrgMap() {
        Map<String, Integer> orgMap = new HashMap<>();
        // 有一个orgId 200w 联系人
        orgMap.put("5e378a1eaace70000aa8fe78", 200_0000);

        // 指定orgId 10w 联系人
        orgMap.put("614aea718b57a8e40fe9bb11", 10_0000);

        // 指定orgId 3w 联系人
        orgMap.put("6144477f7c39f32d7c2120f4", 3_0000);

        // 剩余的随机 总共 2000000联系人
        int surplusNum = 200_0000;
        while (surplusNum > 0) {
            // 随机数生成，生成10到1_0000的随机数
            int memberNum = NumberUtil.generateRandomNumber(10, 10000, 1)[0];
            memberNum = Math.min(memberNum, surplusNum);
            // 塞入随机数量的联系人
            orgMap.put(StringUtil.getId(), memberNum);
            surplusNum -= memberNum;
        }
        return orgMap;
    }

    /**
     * 创建3个标签组【每个标签组，3个标签值】
     * <p>
     * 创建5扩展字段
     *
     * @param orgId        组织id
     * @param memberNumber 联系人数量
     */
    private void buildMemberData(String orgId, int memberNumber) {
        // 创建3个标签组
        String labels = buildMemberLabel(orgId);
        // 创建5个扩展字段
        String fields = buildMemberField(orgId);
        // 开始创建联系人信息
        int index = 0;
        while (memberNumber > 0) {
            final List<MemberEntity> memberList = new ArrayList<>(1000);
            final List<FootprintEntity> footprintEntities = new ArrayList<>(4000);

            // 每1000条提交一个线程
            int alerdyHandleNum = 0;
            for (; alerdyHandleNum < memberNumber; alerdyHandleNum++) {
                if (alerdyHandleNum % 10 == 0) {
                    MemberEntity memberEntity = buildMember(orgId, index++, labels, fields);
                    memberList.add(memberEntity);
                    // 有3个足迹点
                    footprintEntities.add(buildFootprint(memberEntity.getId(), orgId));
                    footprintEntities.add(buildFootprint(memberEntity.getId(), orgId));
                    footprintEntities.add(buildFootprint(memberEntity.getId(), orgId));
                } else {
                    MemberEntity memberEntity = buildMember(orgId, index++, "[]", "[]");
                    memberList.add(memberEntity);
                    // 有2个足迹点
                    footprintEntities.add(buildFootprint(memberEntity.getId(), orgId));
                    footprintEntities.add(buildFootprint(memberEntity.getId(), orgId));
                }
                if (alerdyHandleNum != 0 && alerdyHandleNum % 1000 == 0) {
                    break;
                }
            }
            memberNumber -= alerdyHandleNum;
            // 丢到线程池创建联系人
            BUILD_MEMBER_THREAD_POOL.execute(() -> buildMember(memberList, footprintEntities));
            // buildMember(memberList);
        }
    }

    /**
     * 创建足迹点
     */
    private FootprintEntity buildFootprint(String memberId, String orgId) {
        FootprintEntity entity = new FootprintEntity();
        entity.setId(StringUtil.getId());
        entity.setType(0);
        entity.setOrgId(orgId);
        entity.setMemberId(memberId);
        entity.setSourceKey(memberId);
        entity.setFootprintTime(DateUtil.getCommonDate());
        entity.setContent("");
        entity.setCreateTime(entity.getFootprintTime());
        entity.setUpdateTime(entity.getFootprintTime());
        return entity;
    }

    /**
     * 根据orgId创建3个标签组
     *
     * @param orgId 组织id
     * @return
     */
    private String buildMemberLabel(String orgId) {
        List<HttpMemberLabelParam> labelValueIdDTOS = new ArrayList<>();

        // 1. 创建3个标签组
        Date now = DateUtil.getCommonDate();
        for (int i = 0; i < 3; i++) {
            LabelGroupEntity labelGroupEntity = new LabelGroupEntity();
            labelGroupEntity.setId(StringUtil.getId());
            labelGroupEntity.setOrgId(orgId);
            labelGroupEntity.setName("test" + i);
            labelGroupEntity.setSeq(i + 1);
            labelGroupEntity.setMemberType(0);
            labelGroupEntity.setCreateTime(now);
            labelGroupEntity.setUpdateTime(now);
            labelGroupMapper.saveLabelGroup(labelGroupEntity);
            // 2. 每个标签组创建3个标签
            String id = "";
            String labelId = "";
            for (int j = 0; j < 3; j++) {
                LabelEntity label = new LabelEntity();
                label.setLabelId(StringUtil.getId());
                label.setOrgId(orgId);
                label.setLabelGroupId(labelGroupEntity.getId());
                label.setName("test" + i);
                label.setManual(1);
                label.setAuto(0);
                label.setCreateTime(now);
                label.setUpdateTime(now);
                labelMapper.createLabel(label);
                labelId = label.getLabelId();
                // 3. 每个标签下创建3个标签值
                for (int k = 0; k < 3; k++) {
                    LabelValueEntity labelValueEntity = new LabelValueEntity();
                    labelValueEntity.setLabelValueId(StringUtil.getId());
                    labelValueEntity.setOrgId(orgId);
                    labelValueEntity.setValue("test" + i);
                    labelValueEntity.setSeq(k + 1);
                    labelValueEntity.setLabelId(label.getLabelId());
                    labelValueEntity.setCondition("");
                    labelValueEntity.setMemberType(0);
                    labelValueEntity.setManual(label.getManual());
                    labelValueEntity.setAuto(label.getAuto());
                    labelValueEntity.setLabelName(label.getName());
                    labelValueEntity.setLabelGroupId(labelGroupEntity.getId());
                    labelValueEntity.setLabelGroupName(labelGroupEntity.getName());
                    labelValueEntity.setCreateTime(now);
                    labelValueEntity.setUpdateTime(now);
                    labelValueMapper.createLabelValue(labelValueEntity);
                    id = labelValueEntity.getLabelId();
                }
            }
            // 4. 构建标签json返回
            HttpMemberLabelParam param = new HttpMemberLabelParam();
            param.setId(id);
            param.setLabelId(labelId);
            labelValueIdDTOS.add(param);
        }

        return JSONObject.toJSONString(labelValueIdDTOS);
    }

    private void buildLabel(String orgId) {

        Date now = DateUtil.getCommonDate();
        for (int i = 0; i < 2; i++) {
            LabelGroupEntity labelGroupEntity = new LabelGroupEntity();
            labelGroupEntity.setId(StringUtil.getId());
            labelGroupEntity.setOrgId(orgId);
            labelGroupEntity.setName("test" + i);
            labelGroupEntity.setSeq(i + 1);
            labelGroupEntity.setMemberType(0);
            labelGroupEntity.setCreateTime(now);
            labelGroupEntity.setUpdateTime(now);
            labelGroupMapper.saveLabelGroup(labelGroupEntity);
            // 2. 每个标签组创建3个标签
            String id = "";
            String labelId = "";
            for (int j = 0; j < 2; j++) {
                LabelEntity label = new LabelEntity();
                label.setLabelId(StringUtil.getId());
                label.setOrgId(orgId);
                label.setLabelGroupId(labelGroupEntity.getId());
                label.setName("test" + i);
                label.setManual(1);
                label.setAuto(0);
                label.setCreateTime(now);
                label.setUpdateTime(now);
                labelMapper.createLabel(label);
                labelId = label.getLabelId();
                // 3. 每个标签下创建3个标签值
                if (j % 1 == 0) {
                    for (int k = 0; k < 2; k++) {
                        LabelValueEntity labelValueEntity = new LabelValueEntity();
                        labelValueEntity.setLabelValueId(StringUtil.getId());
                        labelValueEntity.setOrgId(orgId);
                        labelValueEntity.setValue("test" + i);
                        labelValueEntity.setSeq(k + 1);
                        labelValueEntity.setLabelId(label.getLabelId());
                        labelValueEntity.setCondition("");
                        labelValueEntity.setMemberType(0);
                        labelValueEntity.setManual(label.getManual());
                        labelValueEntity.setAuto(label.getAuto());
                        labelValueEntity.setLabelName(label.getName());
                        labelValueEntity.setLabelGroupId(labelGroupEntity.getId());
                        labelValueEntity.setLabelGroupName(labelGroupEntity.getName());
                        labelValueEntity.setCreateTime(now);
                        labelValueEntity.setUpdateTime(now);
                        labelValueMapper.createLabelValue(labelValueEntity);
                        id = labelValueEntity.getLabelId();
                    }
                } else {
                    for (int k = 0; k < 1; k++) {
                        LabelValueEntity labelValueEntity = new LabelValueEntity();
                        labelValueEntity.setLabelValueId(StringUtil.getId());
                        labelValueEntity.setOrgId(orgId);
                        labelValueEntity.setValue("test" + i);
                        labelValueEntity.setSeq(k + 1);
                        labelValueEntity.setLabelId(label.getLabelId());
                        labelValueEntity.setCondition("");
                        labelValueEntity.setMemberType(0);
                        labelValueEntity.setManual(label.getManual());
                        labelValueEntity.setAuto(label.getAuto());
                        labelValueEntity.setLabelName(label.getName());
                        labelValueEntity.setLabelGroupId(labelGroupEntity.getId());
                        labelValueEntity.setLabelGroupName(labelGroupEntity.getName());
                        labelValueEntity.setCreateTime(now);
                        labelValueEntity.setUpdateTime(now);
                        labelValueMapper.createLabelValue(labelValueEntity);
                        id = labelValueEntity.getLabelId();
                    }
                }
            }
        }

    }

    /**
     * 根据orgId创建5个扩展字段
     *
     * @param orgId
     * @return
     */
    private String buildMemberField(String orgId) {
        // 1. 创建5个扩展字段
        List<ExtendFieldEntity> extendFieldEntities = new ArrayList<>();
        List<HttpMemberFieldParam> fieldDTOList = new ArrayList<>();
        Date now = DateUtil.getCommonDate();
        for (int i = 0; i < 5; i++) {
            ExtendFieldEntity extendFieldEntity = new ExtendFieldEntity(StringUtil.getId(), orgId, 0, "test" + i,
                    0, now, now);
            extendFieldEntities.add(extendFieldEntity);
            // 2. 构建扩展字段的json返回
            HttpMemberFieldParam memberExtendFieldDTO = new HttpMemberFieldParam();
            memberExtendFieldDTO.setId(extendFieldEntity.getFieldId());
            memberExtendFieldDTO.setName(extendFieldEntity.getName());
            memberExtendFieldDTO.setValue("自定义填写");
            memberExtendFieldDTO.setType(extendFieldEntity.getType());
            fieldDTOList.add(memberExtendFieldDTO);
        }
        Integer batchInsertResult = extendFieldMapper.batchInsert(extendFieldEntities);
        return JSONObject.toJSONString(fieldDTOList);
    }

    /**
     * 构建联系人对象
     *
     * @param orgId
     * @param i
     * @param labels
     * @param fields
     * @return
     */
    private MemberEntity buildMember(String orgId, int i, String labels, String fields) {
        String id = StringUtil.getId();
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setOrgId(orgId);
        memberEntity.setId(id);
        memberEntity.setSysId("");
        memberEntity.setSource("test");
        memberEntity.setName("test" + i);
        memberEntity.setEmail("www@qq.com");
        memberEntity.setPhone("10000000001");
        memberEntity.setGender("男");
        memberEntity.setStoreId("");
        memberEntity.setStatus(0);
        memberEntity.setContent("");
        memberEntity.setOpenId("");
        memberEntity.setAppId("");
        memberEntity.setAliPayUserId("");
        memberEntity.setAddress("[]");
        memberEntity.setEmployeeId("");
        memberEntity.setEmployeeStatus(0);
        memberEntity.setMemberType(0);
        memberEntity.setBirthday(null);
        memberEntity.setDepartment("");
        memberEntity.setPosition("");
        memberEntity.setInstituteName("");
        memberEntity.setInstituteId("");
        memberEntity.setFieldValList(fields);
        memberEntity.setUserId("");
        memberEntity.setAge(null);
        memberEntity.setLabels(labels);
        memberEntity.setUpdateTime(DateUtil.getCommonDate());
        memberEntity.setCreateTime(memberEntity.getUpdateTime());
        return memberEntity;
    }


    /**
     * 批量创建联系人
     *
     * @param memberList
     * @param footprintEntities
     */
    private void buildMember(List<MemberEntity> memberList, List<FootprintEntity> footprintEntities) {
        memberMapper.batchSave(memberList);
        footprintMapper.batchSave(footprintEntities);
    }

}
